package org.chen;

import org.chen.cache.manager.CacheManager;
import org.chen.cache.manager.RedisConfig;
import org.chen.cache.manager.RedisSource;
import org.chen.example.User;
import org.chen.example.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author: Allen
 * @date: 2017/6/26
 */

@RestController
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
public class Stater {

    @Autowired
    private UserService userService;

    public static void main(String[] args) {
        SpringApplication.run(Stater.class, args);
    }

    /**
     * 创建cache manager
     * @return
     */
    @Bean
    public CacheManager createCacheManager(){
        RedisConfig redisConfig = new RedisConfig();
        redisConfig.setDefaultReadSourceName("read");
        redisConfig.setDefaultWriteSourceName("write");

        JedisPoolConfig config = new JedisPoolConfig();

        //连接耗尽时是否阻塞, false报异常,true 阻塞直到超时, 默认true
        config.setBlockWhenExhausted(true);
        //设置的逐出策略类名, 默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数)
        config.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy");
        //是否启用pool的jmx管理功能, 默认true
        config.setJmxEnabled(true);
        //MBean ObjectName = new ObjectName("org.apache.commons.pool2:type=GenericObjectPool,name=" + "poolConfig" + i); 默认为"poolConfig", JMX不熟,具体不知道是干啥的...默认就好.
        config.setJmxNamePrefix("poolConfig");
        //是否启用后进先出, 默认true
        config.setLifo(true);
        //最大空闲连接数, 默认8个
        config.setMaxIdle(8);
        //最大连接数, 默认8个
        config.setMaxTotal(8);
        //获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
        config.setMaxWaitMillis(-1);
        //逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
        config.setMinEvictableIdleTimeMillis(1800000);
        //最小空闲连接数, 默认0
        config.setMinIdle(0);
        //每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
        config.setNumTestsPerEvictionRun(3);
        //对象空闲多久后逐出, 当空闲时间>该值 且 空闲连接>最大空闲数 时直接逐出,不再根据MinEvictableIdleTimeMillis判断  (默认逐出策略)
        config.setSoftMinEvictableIdleTimeMillis(1800000);
        //在获取连接的时候检查有效性, 默认false
        config.setTestOnBorrow(false);
        //在空闲时检查有效性, 默认false
        config.setTestWhileIdle(false);
        //逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
        config.setTimeBetweenEvictionRunsMillis(-1);
//        poolConfig.setTestWhileIdle(true);
//        poolConfig.setTestOnBorrow(true);

        RedisSource[] sources = new RedisSource[2];
        RedisSource readRedisSource = new RedisSource();
        readRedisSource.setSourceName("read");
        readRedisSource.setIp("192.168.0.118");
        readRedisSource.setPort(6379);
        readRedisSource.setPassword("chen");
        readRedisSource.setPoolConfig(config);

        RedisSource writeRedisSource = new RedisSource();
        writeRedisSource.setSourceName("write");
        writeRedisSource.setIp("192.168.0.118");
        writeRedisSource.setPort(6379);
        writeRedisSource.setPassword("chen");
        writeRedisSource.setPoolConfig(config);

        sources[0] = readRedisSource;
        sources[1] = writeRedisSource;
        redisConfig.setSources(sources);

        redisConfig.setUseLocalCache(true);
        /*
         * 分布式多服务 订阅本地缓存,配置此属性,必须开启本地缓存useLocalCache=true
         */
        redisConfig.setSubscribeLocalCacheChannel(true);

        /**
         * 是否开启缓存key分布式锁
         */
        redisConfig.setDistributedLock(true);

        CacheManager cacheManager = new CacheManager(redisConfig);
        return cacheManager;
    }

    @RequestMapping("/del")
    public String del(@RequestParam(required = false) Integer id) {
        userService.remove(id);
        return ""+new Date();
    }

    @RequestMapping("/get")
    public String get(@RequestParam(required = false) int id) {
        User user = userService.get(id, "test@163.com");
        return user+ " "+new Date();
    }

    @RequestMapping("/batch")
    public String batch(@RequestParam String ids) {
        String[] idArr = ids.split(",");
        List<Integer> list = new ArrayList<>();
        for (String id : idArr) {
            list.add(Integer.valueOf(id));
        }
        List<User> users = userService.batchGet(list);
        return users+" "+new Date();
    }
    @RequestMapping("/batchPut")
    public String batchPut(@RequestParam String ids) {
        String[] idArr = ids.split(",");
        List<Integer> list = new ArrayList<>();
        for (String id : idArr) {
            list.add(Integer.valueOf(id));
        }
        List<User> users = userService.batchPut(list);
        return users+" "+new Date();
    }

    @RequestMapping("/batchRemove")
    public String batchRemove(Integer id,String email) {

        userService.batchRemove(id,email);
        return  new Date().toString();
    }


    @RequestMapping("/batchSlide")
    public String batchSlide(@RequestParam String ids) {
        String[] idArr = ids.split(",");
        List<Integer> list = new ArrayList<>();
        for (String id : idArr) {
            list.add(Integer.valueOf(id));
        }
        List<User> users = userService.batchSlide(list);
        return users+" "+new Date();
    }


}
